﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ErrorCode
{
    /// <summary>
    /// 标准 API 返回结果封装类
    /// </summary>
    /// <typeparam name="T">数据类型</typeparam>
    public class ApiResult<T>
    {
        /// <summary>
        /// 状态码
        /// </summary>
        public ResultCode Code { get; set; }

        /// <summary>
        /// 返回消息
        /// </summary>
        public string Message { get; set; } = string.Empty;

        /// <summary>
        /// 返回数据
        /// </summary>
        public T? Data { get; set; }

        /// <summary>
        /// 时间戳
        /// </summary>
        public long Timestamp { get; set; } = DateTimeOffset.UtcNow.ToUnixTimeSeconds();

        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success => Code == ResultCode.成功;

        #region 构造函数

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public ApiResult()
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="code">状态码</param>
        /// <param name="message">消息</param>
        /// <param name="data">数据</param>
        public ApiResult(ResultCode code, string message, T? data = default)
        {
            Code = code;
            Message = message;
            Data = data;
        }

        #endregion

        #region 成功返回快捷方法

        /// <summary>
        /// 成功返回（带数据）
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="message">消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> SuccessWithData(T data, string message = "操作成功")
        {
            return new ApiResult<T>(ResultCode.成功, message, data);
        }

        /// <summary>
        /// 成功返回（无数据）
        /// </summary>
        /// <param name="message">消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> SuccessMessage(string message = "操作成功")
        {
            return new ApiResult<T>(ResultCode.成功, message);
        }

        #endregion

        #region 失败返回快捷方法

        /// <summary>
        /// 失败返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <param name="code">错误码</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> Fail(string message, ResultCode code = ResultCode.操作失败)
        {
            return new ApiResult<T>(code, message);
        }

        /// <summary>
        /// 参数错误返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> BadRequest(string message = "参数错误")
        {
            return new ApiResult<T>(ResultCode.参数错误, message);
        }

        /// <summary>
        /// 未授权返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> Unauthorized(string message = "未授权访问")
        {
            return new ApiResult<T>(ResultCode.未授权, message);
        }

        /// <summary>
        /// 禁止访问返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> Forbidden(string message = "禁止访问")
        {
            return new ApiResult<T>(ResultCode.禁止访问, message);
        }

        /// <summary>
        /// 资源不存在返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> NotFound(string message = "资源不存在")
        {
            return new ApiResult<T>(ResultCode.资源不存在, message);
        }

        /// <summary>
        /// 服务器错误返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> ServerError(string message = "服务器内部错误")
        {
            return new ApiResult<T>(ResultCode.服务器错误, message);
        }

        /// <summary>
        /// 数据已存在返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> AlreadyExists(string message = "数据已存在")
        {
            return new ApiResult<T>(ResultCode.数据已存在, message);
        }

        /// <summary>
        /// 数据不存在返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> NotExists(string message = "数据不存在")
        {
            return new ApiResult<T>(ResultCode.数据不存在, message);
        }

        #endregion

        #region 条件返回方法

        /// <summary>
        /// 根据条件返回结果
        /// </summary>
        /// <param name="condition">条件</param>
        /// <param name="data">成功时返回的数据</param>
        /// <param name="successMessage">成功消息</param>
        /// <param name="failMessage">失败消息</param>
        /// <param name="failCode">失败状态码</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> Result(bool condition, T? data = default,
            string successMessage = "操作成功", string failMessage = "操作失败",
            ResultCode failCode = ResultCode.操作失败)
        {
            return condition
                ? SuccessWithData(data!, successMessage)
                : Fail(failMessage, failCode);
        }

        /// <summary>
        /// 根据数据是否为空返回结果
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="successMessage">成功消息</param>
        /// <param name="notFoundMessage">未找到消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> ResultIfNotNull(T? data,
            string successMessage = "查询成功", string notFoundMessage = "数据不存在")
        {
            return data != null
                ? SuccessWithData(data, successMessage)
                : NotExists(notFoundMessage);
        }

        #endregion

        #region 异步返回方法

        /// <summary>
        /// 异步成功返回
        /// </summary>
        /// <param name="data">数据</param>
        /// <param name="message">消息</param>
        /// <returns>异步API结果</returns>
        public static Task<ApiResult<T>> SuccessAsync(T data, string message = "操作成功")
        {
            return Task.FromResult(SuccessWithData(data, message));
        }

        /// <summary>
        /// 异步失败返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <param name="code">错误码</param>
        /// <returns>异步API结果</returns>
        public static Task<ApiResult<T>> FailAsync(string message, ResultCode code = ResultCode.操作失败)
        {
            return Task.FromResult(Fail(message, code));
        }

        #endregion

        #region 转换方法

        /// <summary>
        /// 转换数据类型
        /// </summary>
        /// <typeparam name="TResult">目标类型</typeparam>
        /// <param name="converter">转换函数</param>
        /// <returns>转换后的API结果</returns>
        public ApiResult<TResult> Map<TResult>(Func<T, TResult> converter)
        {
            if (!Success || Data == null)
            {
                return new ApiResult<TResult>(Code, Message);
            }

            try
            {
                var convertedData = converter(Data);
                return new ApiResult<TResult>(Code, Message, convertedData);
            }
            catch (Exception ex)
            {
                return ApiResult<TResult>.ServerError($"数据转换失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 转换为无数据的结果
        /// </summary>
        /// <returns>无数据的API结果</returns>
        public ApiResult<object> ToVoidResult()
        {
            return new ApiResult<object>(Code, Message);
        }

        #endregion

        /// <summary>
        /// 重写ToString方法
        /// </summary>
        /// <returns>字符串表示</returns>
        public override string ToString()
        {
            return $"Code: {Code}, Message: {Message}, Success: {Success}, Timestamp: {Timestamp}";
        }

        /// <summary>
        /// 错误返回
        /// </summary>
        /// <param name="code">错误码</param>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static ApiResult<T> Error(ResultCode code, string message)
        {
            return new ApiResult<T>(code, message);
        }
    }

    /// <summary>
    /// 无泛型的 API 返回结果类（用于不需要返回数据的场景）
    /// </summary>
    public class ApiResult : ApiResult<object>
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ApiResult() : base()
        {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="code">状态码</param>
        /// <param name="message">消息</param>
        public ApiResult(ResultCode code, string message) : base(code, message)
        {
        }

        #region 静态快捷方法

        /// <summary>
        /// 成功返回
        /// </summary>
        /// <param name="message">消息</param>
        /// <returns>API结果</returns>
        public static new ApiResult Success(string message = "操作成功")
        {
            return new ApiResult(ResultCode.成功, message);
        }

        /// <summary>
        /// 失败返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <param name="code">错误码</param>
        /// <returns>API结果</returns>
        public static new ApiResult Fail(string message, ResultCode code = ResultCode.操作失败)
        {
            return new ApiResult(code, message);
        }

        /// <summary>
        /// 参数错误返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static new ApiResult BadRequest(string message = "参数错误")
        {
            return new ApiResult(ResultCode.参数错误, message);
        }

        /// <summary>
        /// 未授权返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static new ApiResult Unauthorized(string message = "未授权访问")
        {
            return new ApiResult(ResultCode.未授权, message);
        }

        /// <summary>
        /// 禁止访问返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static new ApiResult Forbidden(string message = "禁止访问")
        {
            return new ApiResult(ResultCode.禁止访问, message);
        }

        /// <summary>
        /// 资源不存在返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static new ApiResult NotFound(string message = "资源不存在")
        {
            return new ApiResult(ResultCode.资源不存在, message);
        }

        /// <summary>
        /// 服务器错误返回
        /// </summary>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static new ApiResult ServerError(string message = "服务器内部错误")
        {
            return new ApiResult(ResultCode.服务器错误, message);
        }

        /// <summary>
        /// 根据条件返回结果
        /// </summary>
        /// <param name="condition">条件</param>
        /// <param name="successMessage">成功消息</param>
        /// <param name="failMessage">失败消息</param>
        /// <param name="failCode">失败状态码</param>
        /// <returns>API结果</returns>
        public static ApiResult Result(bool condition,
            string successMessage = "操作成功", string failMessage = "操作失败",
            ResultCode failCode = ResultCode.操作失败)
        {
            return condition
                ? Success(successMessage)
                : Fail(failMessage, failCode);
        }

        /// <summary>
        /// 错误返回
        /// </summary>
        /// <param name="code">错误码</param>
        /// <param name="message">错误消息</param>
        /// <returns>API结果</returns>
        public static new ApiResult Error(ResultCode code, string message)
        {
            return new ApiResult(code, message);
        }

        #endregion
    }

    /*
     * 使用示例：
     * 
     * 1. 成功返回（带数据）：
     * return ApiResult<TraceabilityInfo>.SuccessWithData(data, "查询成功");
     * 
     * 2. 成功返回（无数据）：
     * return ApiResult.Success("操作成功");
     * return ApiResult<TraceabilityInfo>.SuccessMessage("操作成功");
     * 
     * 3. 失败返回：
     * return ApiResult<TraceabilityInfo>.Fail("查询失败", ResultCode.数据不存在);
     * 
     * 4. 快捷错误返回：
     * return ApiResult<TraceabilityInfo>.NotFound("溯源信息不存在");
     * return ApiResult<TraceabilityInfo>.BadRequest("参数验证失败");
     * return ApiResult<TraceabilityInfo>.Unauthorized("请先登录");
     * 
     * 5. 条件返回：
     * return ApiResult<TraceabilityInfo>.Result(data != null, data, "查询成功", "数据不存在");
     * 
     * 6. 根据数据是否为空返回：
     * return ApiResult<TraceabilityInfo>.ResultIfNotNull(data, "查询成功", "数据不存在");
     * 
     * 7. 数据类型转换：
     * var dtoResult = result.Map(x => new TraceabilityInfoDto { ... });
     * 
     * 8. 异步返回：
     * return await ApiResult<TraceabilityInfo>.SuccessAsync(data, "查询成功");
     * 
     * 9. 在控制器中的典型用法：
     * [HttpGet("{id}")]
     * public async Task<ApiResult<TraceabilityInfo>> GetById(string id)
     * {
     *     var data = await _repository.GetByIdAsync(id);
     *     return ApiResult<TraceabilityInfo>.ResultIfNotNull(data);
     * }
     * 
     * [HttpPost]
     * public async Task<ApiResult> Create(CreateCommand command)
     * {
     *     var result = await _mediator.Send(command);
     *     return ApiResult.Result(result > 0, "创建成功", "创建失败");
     * }
     */
}
